package model.skill;

import utilities.Archive;
import utilities.ModelFactory;
import model.Model;
import model.effect.Effect;
import model.map.Direction;
import model.map.Location;
import model.map.LocationProjection;

/**
 * The abstract type for all Projectiles that defines the common interface to be used to get the affected locations
 */
public abstract class Projectile extends Model {

	private Effect effect;
	private LocationProjection propagationLogic;
	private int range;
	private int speed; 
	
	public Projectile()
	{
		super(SkillType.PROJECTILE);
		effect = null;
		propagationLogic = null;
		range = 1;
		speed = 40;
	}
	
	public Projectile(String name, Effect effect, LocationProjection propagationLogic, int range, int speed)
	{
		super(name);
		this.effect = effect;
		this.propagationLogic = propagationLogic;
		this.range = range;
		this.speed = speed;
	}
	
	public Effect getEffect()
	{
		return effect;
	}
	
	public void setEffect(Effect effect)
	{
		this.effect = effect;
	}
	
	public int getRange()
	{
		return range;
	}
	
	public LocationProjection getPropagationLogic()
	{
		return propagationLogic;
	}
	
	public int getSpeed()
	{
		return speed;
	}
	
	/**
	 * Returns the locations specified by the propagation strategy in use
	 */
	public abstract void propagate(ProjectileInformation projectileInfo);	
	
	
	public Archive save() {
		Archive archive = super.save();
		
		archive.putClassName("effect", this.effect.getClass().getName());
		archive.putOneRelationship("effect", this.effect);
		
		archive.putClassName("propagationLogic", this.propagationLogic.getClass().getName());
		archive.putOneRelationship("propagationLogic", this.propagationLogic);
		
		archive.putAttribute("range", Integer.toString(this.range));
		
		archive.putAttribute("speed", Integer.toString(this.speed));
		
		return archive;
	}
	
	public void load(Archive archive) {
		super.load(archive);
		
		this.effect = (Effect)ModelFactory.getInstance().createInstanceWithClassName(archive.getClassName("effect"));
		this.effect.load(archive.getOneRelationship("effect"));
		
		this.propagationLogic = (LocationProjection)ModelFactory.getInstance().createInstanceWithClassName(archive.getClassName("propagationLogic"));
		this.propagationLogic.load(archive.getOneRelationship("propagationLogic"));
		
		this.range = Integer.parseInt(archive.getAttribute("range"));
		
		this.speed = Integer.parseInt(archive.getAttribute("speed"));
		
	}
}
